/********************************************************************************
* @File name: breathled.c
* @Author: Loganx
* @Gitee: https://gitee.com/loganxiang/lgxsmartcar
* @Version: 1.0(2025-10-09)
* @Description: STC8A单片机七彩LED呼吸灯
********************************************************************************
* 本软件使用了STC的STC8A官方库
********************************************************************************/
#include "breathled.h"

uint8 BLEDBreathMode;
uint8 BLEDColor;
uint16 BLEDScanCycle;

uint16 code ColorRaw[8][3] = {
	{0x0000,0x0000,0x0000},					//OFF
	{BLED_BRIGHT,0x0000,0x0000},			//RED
	{BLED_BRIGHT,BLED_BRIGHT,0x0000},		//YELLOW
	{0x0000,BLED_BRIGHT,0x0000},			//GREEN
	{0x0000,BLED_BRIGHT,BLED_BRIGHT},		//CYAN
	{0x0000,0x0000,BLED_BRIGHT},			//BLUE
	{BLED_BRIGHT,0x0000,BLED_BRIGHT},		//PURPLE
	{BLED_BRIGHT,BLED_BRIGHT,BLED_BRIGHT}};	//WHITE

void BLEDInit(void){
	GPIO_InitTypeDef gpio;
	PWM15_InitTypeDef pwm;
	
	gpio.Mode = GPIO_OUT_PP;
	gpio.Pin = GPIO_Pin_LOW;
	
	GPIO_Inilize(GPIO_P1,&gpio);

	pwm.PWM_Enable = ENABLE;
	pwm.PWM_Period = 0x1000;
	pwm.PWM_Clock_Sel = PWM_CLK_SYS;
	pwm.PWM_Clock_PS = 0;
	pwm.PWM_CInt = DISABLE;
	pwm.PWM_Counter = ENABLE;
	PWM15_Init(&pwm);
	
	PWM15Duty(PWM15_0,0x000,0x1000);
	PWM15Duty(PWM15_1,0x000,0x1000);
	PWM15Duty(PWM15_2,0x000,0x1000);
	PWMChannelCtrl(PWM15_0,ENABLE,PWM15_SW_P1,1,DISABLE,DISABLE,DISABLE);
	PWMChannelCtrl(PWM15_1,ENABLE,PWM15_SW_P1,1,DISABLE,DISABLE,DISABLE);
	PWMChannelCtrl(PWM15_2,ENABLE,PWM15_SW_P1,1,DISABLE,DISABLE,DISABLE);
}

void BLEDTurnOn(uint8 color){
	uint16 *pDuty;
	
	BLEDColor = color;
	BLEDBreathMode = BLED_MODE_OFF;
	pDuty = ColorRaw[color];

	PWM15Duty(PWM15_0,pDuty[0],0x1000);
	PWM15Duty(PWM15_1,pDuty[1],0x1000);
	PWM15Duty(PWM15_2,pDuty[2],0x1000);
}

void BLEDTurnOff(void){
	uint16 *pDuty;
	
	BLEDColor = BLED_COLOR_OFF;
	BLEDBreathMode = BLED_MODE_OFF;
	pDuty = ColorRaw[0];
	
	PWM15Duty(PWM15_0,pDuty[0],0x1000);
	PWM15Duty(PWM15_1,pDuty[1],0x1000);
	PWM15Duty(PWM15_2,pDuty[2],0x1000);
}

void BLEDBreath(uint8 mode,uint8 color){
	BLEDColor = color;
	BLEDBreathMode = mode;
	BLEDScanCycle = 0;
}

void BLEDSetColor(uint8 red,uint8 green,uint8 blue){
	PWM15Duty(PWM15_0,red << 4,0x1000);
	PWM15Duty(PWM15_1,red << 4,0x1000);
	PWM15Duty(PWM15_2,red << 4,0x1000);
}

//Systick callback(20ms)
void SystickCallbackBLED(void){
	uint16 *pDuty;
	
	if(BLEDBreathMode == BLED_MODE_SINGLE){
		pDuty = ColorRaw[BLEDColor];
		
		if(++BLEDScanCycle > 128)
			BLEDScanCycle = 0;
		if(BLEDScanCycle < 64){
			PWM15Duty(PWM15_0,pDuty[0] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle,0x1000);
			PWM15Duty(PWM15_1,pDuty[1] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle,0x1000);
			PWM15Duty(PWM15_2,pDuty[2] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle,0x1000);
		}
		else{
			PWM15Duty(PWM15_0,pDuty[0] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle),0x1000);
			PWM15Duty(PWM15_1,pDuty[1] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle),0x1000);
			PWM15Duty(PWM15_2,pDuty[2] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle),0x1000);
		}
	}
	else if(BLEDBreathMode == BLED_MODE_COLOR){
		if(++BLEDScanCycle > 448)
			BLEDScanCycle = 0;
		if(BLEDScanCycle < 64){
			PWM15Duty(PWM15_0,BLED_BRIGHT,0x1000);
			PWM15Duty(PWM15_1,(BLED_BRIGHT >> 6) * BLEDScanCycle,0x1000);
			PWM15Duty(PWM15_2,0x0000,0x1000);
		}
		else if(BLEDScanCycle < 128){
			PWM15Duty(PWM15_0,BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-64),0x1000);
			PWM15Duty(PWM15_1,BLED_BRIGHT,0x1000);
			PWM15Duty(PWM15_2,0x0000,0x1000);
		}
		else if(BLEDScanCycle < 192){
			PWM15Duty(PWM15_0,0x0000,0x1000);
			PWM15Duty(PWM15_1,BLED_BRIGHT,0x1000);
			PWM15Duty(PWM15_2,(BLED_BRIGHT >> 6) * (BLEDScanCycle-128),0x1000);
		}
		else if(BLEDScanCycle < 256){
			PWM15Duty(PWM15_0,0x0000,0x1000);
			PWM15Duty(PWM15_1,BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-192),0x1000);
			PWM15Duty(PWM15_2,BLED_BRIGHT,0x1000);
		}
		else if(BLEDScanCycle < 320){
			PWM15Duty(PWM15_0,(BLED_BRIGHT >> 6) * (BLEDScanCycle-256),0x1000);
			PWM15Duty(PWM15_1,0x0000,0x1000);
			PWM15Duty(PWM15_2,BLED_BRIGHT,0x1000);
		}
		else if(BLEDScanCycle < 384){
			PWM15Duty(PWM15_0,BLED_BRIGHT,0x1000);
			PWM15Duty(PWM15_1,0x0000,0x1000);
			PWM15Duty(PWM15_2,BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-320),0x1000);
		}
	}
	else
		BLEDScanCycle = 0;
}